//
//  WMSheetView.m
//  SheetView
//
//  Created by 禹昊 on 2019/1/7.
//  Copyright © 2019年 禹昊. All rights reserved.
//

#import "WMSheetView.h"
@interface WMSheetView()<UIGestureRecognizerDelegate>
@property (nonatomic, assign) CGFloat mininumDisplayHeight;
@property (nonatomic, assign) CGFloat maxinumDisplayHeight;
@property (nonatomic, assign) BOOL isFirstLayout;
@property (nonatomic, assign) CGRect minFrame;
@property (nonatomic, assign) CGRect maxFrame;
@end
@implementation WMSheetView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self originalSet];
    }
    return self;
}
- (instancetype)init {
    if (self = [super init]) {
        [self originalSet];
    }
    return self;
}
- (void)originalSet {
    self.defaultMaxinumDisplayHeight = 300;
    self.defaultMininumDisplayHeight = 100;
    self.triggerVelocity = 1000;
    self.triggerDistance = 50;
    self.displayState = minDisplay;
    self.mininumDisplayHeight = 100;
    self.maxinumDisplayHeight = 300;
    self.isFirstLayout = YES;
}



- (void)setScrollView:(UIScrollView *)contentView {
    self.contentView = contentView;
    self.clipsToBounds = YES;
    self.backgroundColor = [UIColor clearColor];
    contentView.bounces = NO;
    if ([contentView isKindOfClass:[UITableView class]]) {
        ((UITableView *)contentView).estimatedRowHeight = 0;
    }
    [self addSubview: contentView];
    [contentView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    pan.delegate = self;
    [contentView addGestureRecognizer:pan];
}

- (void)panAction:(UIPanGestureRecognizer *)recognizer {
    if (self.mininumDisplayHeight == self.maxinumDisplayHeight) {
        return;
    }
    switch (recognizer.state) {
        case UIGestureRecognizerStateChanged:{
            BOOL canMoveFrame = NO;
            if (self.displayState == minDisplay) {
                canMoveFrame = YES;
            } else {
                if (self.contentView.frame.origin.y > self.maxFrame.origin.y || self.contentView.contentOffset.y <= 0) {
                    canMoveFrame = YES;
                }
            }
            if (canMoveFrame) {
                CGPoint point = [recognizer translationInView:self.contentView];
                CGRect frame = self.contentView.frame;
                frame.origin.y += point.y;
                frame.origin.y = MAX(frame.origin.y, self.maxFrame.origin.y);
                frame.origin.y = MIN(frame.origin.y, self.minFrame.origin.y);
                self.contentView.frame = frame;
            }
            [recognizer setTranslation:CGPointZero inView:self.contentView];
            if (self.displayState == minDisplay) {
                
                if (self.contentView.frame.origin.y <= self.maxFrame.origin.y) {
                    self.displayState = maxDisplay;
                    if ([self.delegate respondsToSelector:@selector(state:willDisplayState:)]) {
                        [self.delegate state:self willDisplayState:maxDisplay];
                    }
                    if ([self.delegate respondsToSelector:@selector(state:didDisplayedSate:)]) {
                        [self.delegate state:self didDisplayedSate:maxDisplay];
                    }
                }
            }
            else {
                
                
                if (self.contentView.frame.origin.y >= self.minFrame.origin.y) {
                    
                    
                    self.displayState = minDisplay;
                    if ([self.delegate respondsToSelector:@selector(state:willDisplayState:)]) {
                        [self.delegate state:self willDisplayState:minDisplay];
                    }
                    if ([self.delegate respondsToSelector:@selector(state:didDisplayedSate:)]) {
                        [self.delegate state:self didDisplayedSate:minDisplay];
                    }
                }
            }
            if (self.contentView.frame.origin.y > self.maxFrame.origin.y || (self.contentView.frame.origin.y == self.minFrame.origin.y && self.contentView.frame.origin.y == self.maxFrame.origin.y)) {
                //当contentView本身还未滚动到最大显示值时，内部的内容不允许滚动。mininumDisplayHeight = maxinumDisplayHeight时也不允许内部内容滚动。
                [self.contentView setContentOffset:CGPointZero animated:NO];
            }
        }
            break;
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateFailed:{
            CGPoint velocity = [recognizer velocityInView:recognizer.view];
            if (self.displayState == minDisplay) {
                if (velocity.y < -self.triggerVelocity) {
                    [self displayMax];
                } else if (self.minFrame.origin.y - self.contentView.frame.origin.y > self.triggerDistance) {
                    if (velocity.y <= 0) {
                        //往上滚
                        [self displayMax];
                    } else {
                        //往下滚
                        [self displayMin];
                    }
                }else {
                    [self displayMin];
                }
                [self.contentView setContentOffset:CGPointZero animated:NO];
            } else {
                if (velocity.y > self.triggerVelocity && self.contentView.contentOffset.y <= 0) {
                    [self displayMin];
                    [self.contentView setContentOffset:CGPointZero animated:NO];
                } else if (self.contentView.frame.origin.y - self.maxFrame.origin.y > self.triggerDistance){
                    if (velocity.y < 0) {
                         //往上滚
                        [self displayMax];
                    } else {
                        //往下滚
                        [self displayMin];
                    }
                } else {
                    [self displayMax];
                }
            }
        }
            break;
        default:
            break;
    }
    
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentSize"]) {
        self.mininumDisplayHeight = MIN(self.defaultMininumDisplayHeight, self.contentView.contentSize.height);
        self.maxinumDisplayHeight = MIN(self.defaultMaxinumDisplayHeight, self.contentView.contentSize.height);
        
        if (self.displayState == maxDisplay) {
            self.contentView.frame = self.maxFrame;
            
        } else {
            self.contentView.frame = self.minFrame;
        }
    }
}
- (void)displayMax {
    if (CGRectEqualToRect(self.contentView.frame, self.maxFrame)) {
        return;
    }
    if ([self.delegate respondsToSelector:@selector(state:willDisplayState:)]) {
        [self.delegate state:self willDisplayState:maxDisplay];
    }
    __weak typeof(self)weakSelf = self;
    [UIView animateWithDuration:0.25 animations:^{
        weakSelf.contentView.frame = weakSelf.maxFrame;
    } completion:^(BOOL finished) {
        weakSelf.displayState = maxDisplay;
        if ([weakSelf.delegate respondsToSelector:@selector(state:didDisplayedSate:)]) {
            [weakSelf.delegate state:weakSelf didDisplayedSate:maxDisplay];
        }
    }];
}
- (void)displayMin {
    if (CGRectEqualToRect(self.contentView.frame, self.minFrame)) {
        return;
    }
    if ([self.delegate respondsToSelector:@selector(state:willDisplayState:)]) {
        [self.delegate state:self willDisplayState:minDisplay];
    }
    __weak typeof(self)weakSelf = self;
    [UIView animateWithDuration:0.25 animations:^{
        weakSelf.contentView.frame = weakSelf.minFrame;
    } completion:^(BOOL finished) {
        weakSelf.displayState = minDisplay;
        if ([weakSelf.delegate respondsToSelector:@selector(state:didDisplayedSate:)]) {
            [weakSelf.delegate state:weakSelf didDisplayedSate:minDisplay];
        }
    }];
}
- (void)layoutSubviews {
    [super layoutSubviews];
    if (self.isFirstLayout) {
        self.isFirstLayout = NO;
        if (self.displayState == minDisplay) {
            self.contentView.frame = self.minFrame;
        } else {
            self.contentView.frame = self.maxFrame;
        }
    }
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if (newSuperview == nil) {
        [self.contentView removeObserver:self forKeyPath:@"contentSize"];
    }
}
- (BOOL)insidePoint:(CGPoint)point WithEvent:(UIEvent *)event {
    return [self convertPoint:point toView:self.contentView].y >= 0;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
- (CGRect)minFrame {
    return CGRectMake(0, self.bounds.size.height - self.mininumDisplayHeight, self.bounds.size.width, self.maxinumDisplayHeight);
}
- (CGRect)maxFrame {
    return CGRectMake(0, self.bounds.size.height - self.maxinumDisplayHeight, self.bounds.size.width, self.maxinumDisplayHeight);
}
- (void)setDefaultMaxinumDisplayHeight:(CGFloat)defaultMaxinumDisplayHeight {
    _defaultMaxinumDisplayHeight = defaultMaxinumDisplayHeight;
    self.maxinumDisplayHeight = defaultMaxinumDisplayHeight;
}
- (void)setDefaultMininumDisplayHeight:(CGFloat)defaultMininumDisplayHeight {
    _defaultMininumDisplayHeight = defaultMininumDisplayHeight;
    self.mininumDisplayHeight = defaultMininumDisplayHeight;
}


- (void)dealloc {
    [self removeObserver:self forKeyPath:@"contentSize"];
}
@end
